#ifndef TD_TILEMAP_H_
#define TD_TILEMAP_H_

/************************************************************************/
/* STL                                                                  */
/************************************************************************/
#include <vector> 
#include <string>
#include <iostream>
#include <fstream>


/************************************************************************/
/* Core                                                                 */
/************************************************************************/
#include "Core/BaseEntity.h"
#include "Core/Matrix2D.h"

/************************************************************************/
/* Resources                                                            */
/************************************************************************/
#include "Resources/Tiles/Tileset.h"

/************************************************************************/
/* Game                                                                 */
/************************************************************************/
#include "Game/GameCore.h"


using namespace TD_Core;

namespace TD_Resources {
	class Tilemap : public BaseEntity {
	
	protected:
		/**The tile set that the map is working on.*/
		const Tileset *m_pTileset;
		
		/**Mapping info: */
		Coord2D m_numTiles;
		Coord2D m_tileSize;

		/**The vector of instantiated tiles.*/
		vector<Tile *> m_tileVector;

		//Storage area for the tile map matrix
		Matrix2D *m_pTilemapMatrix;

		/************************************************************************/
		/* Protected functions                                                  */
		/************************************************************************/

		bool borderlineTop(unsigned int i, unsigned int j);
		bool borderlineBottom(unsigned int i, unsigned j);
		bool borderlineLeft(unsigned int i, unsigned int j);
		bool borderlineRight(unsigned int i, unsigned int j);

		virtual Tile * createNewTile(unsigned int i, unsigned int j, unsigned int x, unsigned int y, int relativePosition);
		

		bool loadTileMatrix(const string &tileMapStr);
	
	public:
		
		/************************************************************************/
		/* ctors and dtors                                                      */
		/************************************************************************/
		
		explicit Tilemap();

		explicit Tilemap(const Tilemap &rhs);

		Tilemap & operator=(const Tilemap &rhs);

		explicit Tilemap(const Tileset *g_pTileset);

		~Tilemap();
		
		/************************************************************************/
		/* Access functions                                                     */
		/************************************************************************/
		inline const Tileset * const getTileset() const {
			return(m_pTileset);
		}
		
		inline const Coord2D & getNumberOfTiles() const {
			return(m_numTiles);
		}

		inline const Coord2D & getTilesize() const {
			return(m_tileSize);
		}

		inline const vector<Tile * > & getTileVector() const {
			return(m_tileVector);
		}

		inline const Matrix2D & getTileMatrix() const {
			return(*m_pTilemapMatrix);
		}
	
		/************************************************************************/
		/* Functionalities                                                      */
		/************************************************************************/
		virtual bool loadTilemap(const string &tileMapStr, const Coord2D & mapPosition, const Coord2D &tileSize, const Coord2D &numTiles);

		
		/************************************************************************/
		/* Rendering                                                            */
		/************************************************************************/
		virtual void render(SDL_Surface *const g_destSurface, unsigned int timeDelta) ;

	};
}
#endif